<HTML>
<HEAD>
<TITLE>[Chapter 10] 10.8 Putting It All Together</TITLE>
<META NAME="author" CONTENT="John Zukowski">
<META NAME="date" CONTENT="Thu Jul 31 14:46:39 1997">
<META NAME="form" CONTENT="html">
<META NAME="metadata" CONTENT="dublincore.0.1">
<META NAME="objecttype" CONTENT="book part">
<META NAME="otheragent" CONTENT="gmat dbtohtml">
<META NAME="publisher" CONTENT="O'Reilly &amp; Associates, Inc.">
<META NAME="source" CONTENT="SGML">
<META NAME="subject" CONTENT="Java AWT">
<META NAME="title" CONTENT="Java AWT">
<META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
</HEAD>
<body vlink="#551a8b" alink="#ff0000" text="#000000" bgcolor="#FFFFFF" link="#0000ee">

<DIV CLASS=htmlnav>
<H1><a href='index.htm'><IMG SRC="gifs/smbanner.gif"
     ALT="Java AWT" border=0></a></H1>
<table width=515 border=0 cellpadding=0 cellspacing=0>
<tr>
<td width=172 align=left valign=top><A HREF="ch10_07.htm"><IMG SRC="gifs/txtpreva.gif" ALT="Previous" border=0></A></td>
<td width=171 align=center valign=top><B><FONT FACE="ARIEL,HELVETICA,HELV,SANSERIF" SIZE="-1">Chapter 10<br>Would You Like to Choose from the Menu?</FONT></B></TD>
<td width=172 align=right valign=top><A HREF="ch10_09.htm"><IMG SRC="gifs/txtnexta.gif" ALT="Next" border=0></A></td>
</tr>
</table>

&nbsp;
<hr align=left width=515>
</DIV>
<DIV CLASS=sect1>
<h2 CLASS=sect1><A CLASS="TITLE" NAME="JAWT-CH-10-SECT-8">10.8 Putting It All Together</A></h2>

<P CLASS=para>
<A NAME="CH10.MENU5"></A>Now that you know about all the different menu classes, it is time to show 
an example. <A HREF="ch10_08.htm#JAWT-CH-10-EX-1">Example 10.1</A> contains the code to put up 
a functional <tt CLASS=literal>MenuBar</tt> attached 
to a <tt CLASS=literal>Frame</tt>, using the 1.0 event 
model. <A HREF="ch10_01.htm#JAWT-CH-10-FIG-2">Figure 10.2</A> (earlier in the chapter) displays the resulting screen. 
The key parts to examine are how the menus are put together in the <tt CLASS=literal>MenuTest</tt> 
constructor and how their actions are handled within <tt CLASS=literal>action()</tt>. 
I implement one real action in the example: the one that terminates the 
application when the user chooses Quit. Any other action 
just displays the label of the item and (if it was a <tt CLASS=literal>CheckBoxMenuItem</tt>) 
the item's state, to give you an idea of how you can use the information 
returned in the event. 

<DIV CLASS=example>
<h4 CLASS=example><A CLASS="TITLE" NAME="JAWT-CH-10-EX-1">Example 10.1: MenuTest 1.0 Source Code</A></h4>

<DIV CLASS=screen>
<P>
<PRE>
import java.awt.*;
public class MenuTest extends Frame {
    MenuTest () {
        super ("MenuTest");
        MenuItem mi;
        Menu file = new Menu ("File", true);
        file.add ("Open");
        file.add (mi = new MenuItem ("Close"));
        mi.disable();
        Menu extras = new Menu ("Extras", false);
        extras.add (new CheckboxMenuItem ("What"));
        extras.add ("Yo");
        extras.add ("Yo");
        file.add (extras);
        file.addSeparator();
        file.add ("Quit");
        Menu help = new Menu("Help");
        help.add ("About");
        MenuBar mb = new MenuBar();
        mb.add (file);
        mb.add (help);
        mb.setHelpMenu (help);
        setMenuBar (mb);
        resize (200, 200);
    }
    public boolean handleEvent (Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            System.exit(0);
        }
        return super.handleEvent (e);
    }
    public boolean action (Event e, Object o) {
        if (e.target instanceof MenuItem) {
            if ("Quit".equals (o)) {
                dispose();
                System.exit(1);
            } else {
                System.out.println ("User selected " + o);
                if (e.target instanceof CheckboxMenuItem) {
                    CheckboxMenuItem cb = (CheckboxMenuItem)e.target;
                    System.out.println ("The value is: " + cb.getState());
                }
            }
            return true;
        }
        return false;
    }
    public static void main (String []args) {
        MenuTest f = new MenuTest ();
        f.show();
    }
}
</PRE>
</DIV>

</DIV>

<P CLASS=para>
The <tt CLASS=literal>MenuTest</tt> constructor builds 
all the menus, creates a menu bar, adds the menus to the menu bar, and 
adds the menu bar to the <tt CLASS=literal>Frame</tt>. 
To show what is possible, I've included a submenu, a separator bar, 
a disabled item, and a help menu. 

<P CLASS=para>
The <tt CLASS=literal>handleEvent()</tt> method exists 
to take care of <tt CLASS=literal>WINDOW_DESTROY</tt> 
events, which are generated if the user uses a native command to exit from 
the window. 

<P CLASS=para>
The <tt CLASS=literal>action()</tt> method does the 
work; it received the action events generated whenever the user selects 
a menu. We ignore most of them, but a real application would need to 
do more work figuring out the user's selection. As it is, <tt CLASS=literal>action()</tt> 
is fairly simple. If the user selected a menu item, we check to see whether 
the item's label was "Quit"; if it was, we exit. If the 
user selected anything else, we print the selection and return <tt CLASS=literal>true</tt> 
to indicate that we handled the event. 

<DIV CLASS=sect2>
<h3 CLASS=sect2><A CLASS="TITLE" NAME="JAWT-CH-10-SECT-8.1">Using Java 1.1 Events</A></h3>

<P CLASS=para>
<A NAME="CH10.EVENT4"></A><A NAME="CH10.EVENT4A"></A><A HREF="ch10_08.htm#JAWT-CH-10-EX-2">Example 10.2</A> uses the Java 1.1 event model but is 
otherwise very similar to <A HREF="ch10_08.htm#JAWT-CH-10-EX-1">Example 10.1</A>. Take a close 
look at the differences and similarities. Although the code that builds 
the GUI is basically the same in both examples, the event handling is completely 
different. The helper class <tt CLASS=literal>MyMenuItem</tt> 
is necessary to simplify event handling. In Java 1.1, every menu item can 
be an event source, so you have to register a listener for each item. Rather 
than calling <tt CLASS=literal>addActionListener()</tt> 
explicitly for each item, we create a subclass of <tt CLASS=literal>MenuItem</tt> 
that registers a listener automatically. The listener is specified in the 
constructor to <tt CLASS=literal>MyMenuItem</tt>; 
in this example, the object that creates the menus (<tt CLASS=literal>MenuTest12</tt>) 
always registers itself as the listener. An alternative would be to override 
<tt CLASS=literal>processActionEvent()</tt> in <tt CLASS=literal>MyMenuItem</tt>, 
but then we'd also need to write a subclass for <tt CLASS=literal>CheckboxMenuItem</tt>. 

<P CLASS=para>
Having said all that, the code is relatively simple. <tt CLASS=literal>MenuTest12</tt> 
implements <tt CLASS=literal>ActionListener</tt> so 
it can receive action events from the menus. As I noted previously, it registers 
itself as the listener for every menu item when it builds the interface. 
The <tt CLASS=literal>actionPerformed()</tt> method 
is called whenever the user selects a menu item; the logic of this method 
is virtually the same as it was in <A HREF="ch10_08.htm#JAWT-CH-10-EX-1">Example 10.1</A>. Notice, 
though, that we use <tt CLASS=literal>getActionCommand()</tt> 
to read the label of the menu item. (Note also that <tt CLASS=literal>getActionCommand()</tt> 
doesn't necessarily return the label; you can change the command 
associated with the menu item by calling <tt CLASS=literal>setActionCommand()</tt>.) 
Similarly, we call the event's <tt CLASS=literal>getSource()</tt> 
method to get the menu item that actually generated the event; we need 
this to figure out whether the user selected a <tt CLASS=literal>CheckboxMenuItem</tt> 
(which implements <tt CLASS=literal>ItemSelectable</tt>). 

<P CLASS=para>
We override <tt CLASS=literal>processWindowEvent()</tt> 
so that we can receive <tt CLASS=literal>WINDOW_CLOSING</tt> 
events without registering a listener. Window closings occur when the user 
uses the native display manager to close the application. If one of these 
events arrives, we shut down cleanly. To make sure that we receive window 
events even if there are no listeners, the <tt CLASS=literal>MenuTest12</tt> 
constructor calls <tt CLASS=literal>enableEvents(WINDOW_EVENT_MASK)</tt>. 

<DIV CLASS=example>
<h4 CLASS=example><A CLASS="TITLE" NAME="JAWT-CH-10-EX-2">Example 10.2: MenuTest12 Source Code, Using Java 1.1 Event Handling</A></h4>

<DIV CLASS=screen>
<P>
<PRE>
// Java 1.1 only
import java.awt.*;
import java.awt.event.*;
public class MenuTest12 extends Frame implements ActionListener {
    class MyMenuItem extends MenuItem {
        public MyMenuItem (String s, ActionListener al) {
            super (s);
            addActionListener (al);
        }
    }
    public MenuTest12 () {
        super ("MenuTest");
        MenuItem mi;
        Menu file = new Menu ("File", true);
        file.add (new MyMenuItem ("Open", this));
        mi = file.add (new MyMenuItem ("Close", this));
        mi.setEnabled (false);
        Menu extras = new Menu ("Extras", false);
        mi = extras.add (new CheckboxMenuItem ("What"));
        mi.addActionListener(this);
        mi = extras.add (new MyMenuItem ("Yo", this));
        mi.setActionCommand ("Yo1");
        mi = extras.add (new MyMenuItem ("Yo", this));
        mi.setActionCommand ("Yo2");
        file.add (extras);
        file.addSeparator();
        file.add (new MyMenuItem ("Quit", this));
        Menu help = new Menu("Help");
        help.add (new MyMenuItem ("About", this));
        MenuBar mb = new MenuBar();
        mb.add (file);
        mb.add (help);
        mb.setHelpMenu (help);
        setMenuBar (mb);
        setSize (200, 200);
        enableEvents (AWTEvent.WINDOW_EVENT_MASK);
    }
// Cannot override processActionEvent since method of MenuItem
// Would have to subclass both MenuItem and CheckboxMenuItem
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Quit")) {
            System.exit(0);
        }
        System.out.println ("User selected " + e.getActionCommand());
        if (e.getSource() instanceof ItemSelectable) {
            ItemSelectable is = (ItemSelectable)e.getSource();
            System.out.println ("The value is: " +
                (is.getSelectedObjects().length != 0)));
        }
    }
    protected void processWindowEvent(WindowEvent e) {
        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
            // Notify others we are closing
            super.processWindowEvent(e);
            System.exit(0);
        } else {
            super.processWindowEvent(e);
        }
    }
    public static void main (String []args) {
        MenuTest12 f = new MenuTest12 ();
        f.show();
    }
}
</PRE>
</DIV>

</DIV>

<P CLASS=para>
I took the opportunity when writing the 1.1 code to make one additional improvement 
to the program. By using action commands, you can easily differentiate 
between the two Yo menu items. Just call <tt CLASS=literal>setActionCommand()</tt> 
to assign a different command to each item. (I used "Yo1" and 
"Yo2".) You could also differentiate between the items by saving 
a reference to each menu item, calling <tt CLASS=literal>getSource()</tt> 
in the event handler, and comparing the result to the saved references. 
However, if the <tt CLASS=literal>ActionListener</tt> 
is another class, it would need access to those references. Using action 
commands is simpler and results in a cleaner event handler. 

<P CLASS=para>
The intent of the <tt CLASS=literal>setActionCommand()</tt> 
and <tt CLASS=literal>getActionCommand()</tt> methods 
is more for internationalization support. For example, you could use <tt CLASS=literal>setActionCommand()</tt> 
to associate the command Quit with a menu item, then set 
the item's label to the appropriate text for the user's locality. 

</DIV>

</DIV>


<DIV CLASS=htmlnav>

<P>
<HR align=left width=515>
<table width=515 border=0 cellpadding=0 cellspacing=0>
<tr>
<td width=172 align=left valign=top><A HREF="ch10_07.htm"><IMG SRC="gifs/txtpreva.gif" ALT="Previous" border=0></A></td>
<td width=171 align=center valign=top><a href="index.htm"><img src='gifs/txthome.gif' border=0 alt='Home'></a></td>
<td width=172 align=right valign=top><A HREF="ch10_09.htm"><IMG SRC="gifs/txtnexta.gif" ALT="Next" border=0></A></td>
</tr>
<tr>
<td width=172 align=left valign=top>MenuBar</td>
<td width=171 align=center valign=top><a href="index/idx_a.htm"><img src='gifs/index.gif' alt='Book Index' border=0></a></td>
<td width=172 align=right valign=top>PopupMenu</td>
</tr>
</table>
<hr align=left width=515>

<IMG SRC="gifs/smnavbar.gif" USEMAP="#map" BORDER=0> 
<MAP NAME="map"> 
<AREA SHAPE=RECT COORDS="0,0,108,15" HREF="../javanut/index.htm"
alt="Java in a Nutshell"> 
<AREA SHAPE=RECT COORDS="109,0,200,15" HREF="../langref/index.htm" 
alt="Java Language Reference"> 
<AREA SHAPE=RECT COORDS="203,0,290,15" HREF="../awt/index.htm" 
alt="Java AWT"> 
<AREA SHAPE=RECT COORDS="291,0,419,15" HREF="../fclass/index.htm" 
alt="Java Fundamental Classes"> 
<AREA SHAPE=RECT COORDS="421,0,514,15" HREF="../exp/index.htm" 
alt="Exploring Java"> 
</MAP>
</DIV>

</BODY>
</HTML>
